# 实战篇 5:为天气页面制作雨雪效果的粒子系统
经过前两节的内容,基本天气预报页面的布局和数据交互都已经完成了,本节来介绍使用小程序的绘图 API 在「实时天气」模块上做一个雨雪效果。

# 小程序的绘图 API
小程序的绘图 API 跟 HTML5 的 Canvas 本质上有很大区别的,造成用法区别的原因是:
小程序的绘图(Canvas)是客户端实现的 Native UI 组件,而不是普通的 H5 组件,所以在使用上跟普通的 H5 组件用法略有不同。
Tips: 微信的 Canvas 在 iOS 上是 Ejecta 实现的。
# 上下文获取方式不同
小程序绘图 API 的 canvasContext 获取方式是通过 <canvas> 的 canvas-id 来获取的,即
<canvas canvas-id="test"></canvas>
获取 Context:
let ctx = wx.createCanvasContext('test')
# API 写法不同
小程序的绘图 API 跟 HTML5 的 Canvas 在用法上主要是绝大部分的 HTML5 Canvas 属性写法,变成了小程序的方法写法,例如:
const ctx = wx.createCanvasContext('myCanvas')
ctx.setFillStyle('red')
ctx.fillRect(10, 10, 150, 75)
ctx.draw()
不过值得一提的是,在 1.9.0 基础库以上,类似 fillStyle、lineWidth 这类的,可以直接跟 H5 的写法一样,不需要使用 setXxxx 的方式了。
# 想要显示绘制效果,需要 ctx.draw() 使用
在小程序的绘图使用中,对 context 进行绘制之后,并不会立即绘制到画布上,而是通过执行 ctx.draw() 的方式,将之前在绘图上下文中的描述(路径、变形、样式)画到 canvas 中。ctx.draw() 方法比较消耗性能,因此不建议在一个绘制周期内多次调用。
Tips: 小程序绘图中的内部尺寸单位都是 px,例如
clearRect()这类方法,所以在使用rpx布局的页面中,需要注意 Canvas 内部 rpx 到 px 的转换关系,详细解释见本节粒子系统实现部分。
# 粒子系统设计思路
在 Canvas 开发中,经常会提到粒子系统,使用粒子系统可以模拟出火、雾、云、雪、尘埃、烟气等抽象视觉效果。
在这个小程序中,笔者使用粒子系统做了雨雪效果,通过雨雪效果的编写,可以让读者学会粒子系统的基础知识,以及在小程序中使用绘图 API 相关的接口。
本小册中的粒子系统由基类和子类组成。Particle 是基类,定义了子类统一的方法,如 run()、stop()、clear() 等。基类负责整个粒子系统动画周期和流程的维护,子类负责具体实现的粒子效果,比如下雨下雪的效果是子类实现的,而下雨下雪的开关和公共处理流程是基类控制的。
基类由如下几个方法组成:
_init():实例化时第一执行的方法;空,由子类具体实现_draw():每个动效周期内画图用的方法;空,由子类具体实现run:设置定时器,定时执行_draw(),实现动画周期stop:停止动画clea
